home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1995 / MacHack 1995.toast / Presentations / Presentations ’91 / MPW Stand-Alone Libraries / Macros.a < prev    next >
Text File  |  1991-06-13  |  10KB  |  521 lines

  1. ;These macros are for the 68000.
  2. ;They have not been optimized for the 68010, 68020 or 68030.
  3.  
  4. ;Some of these macros work only in supervisor mode on a
  5. ;68000 due to use of screwed up CCR instructions.
  6.  
  7. ;Do an EQU if the symbol is not already defined.
  8.     MACRO
  9. &symbol    Default    &value
  10.         IF &Type(&symbol)='UNDEFINED' THEN
  11.             &symbol: EQU &value
  12.         ENDIF
  13.     ENDM
  14.  
  15. ;Ensure that a condition is true.
  16.     MACRO
  17.     Ensure &condition
  18.         IF &Eval(&condition)=0 THEN
  19.             AERROR 'Ensure failed.'
  20.         ENDIF
  21.     ENDM
  22.  
  23. ;End a RECORD and declare a size field.
  24.     MACRO
  25.     ENDRSize
  26.         ORG
  27.         size: EQU *
  28.         ENDR
  29.     ENDM
  30.  
  31. ;Reserve space on a stack.
  32.     MACRO
  33.     RSRV.&size &number
  34.         LCLA &bytes
  35.         IF &number = '' THEN
  36.             &bytes: SETA 1
  37.         ELSE
  38.             &bytes: SETA &Eval(&number)
  39.         ENDIF
  40.         IF &size='L' THEN
  41.             &bytes: SETA 4*&bytes
  42.         ELSEIF &size='W' THEN
  43.             &bytes: SETA 2*&bytes
  44.         ELSEIF &size='B' THEN
  45.         ELSE
  46.             AERROR &CONCAT('RSRV: ',&size,' is a bad size.')
  47.         ENDIF
  48.         &bytes: SETA ((&bytes+1) AND (~1))
  49.         IF &bytes<32767 THEN
  50.             SUB.W #&bytes,SP
  51.         ELSE
  52.             SUB.L #&bytes,SP
  53.         ENDIF
  54.     ENDM
  55.  
  56. ;Free space from a stack.
  57.     MACRO
  58.     FREE.&size &number
  59.         LCLA &bytes
  60.         IF &number = '' THEN
  61.             &bytes: SETA 1
  62.         ELSE
  63.             &bytes: SETA &Eval(&number)
  64.         ENDIF
  65.         IF &size='L' THEN
  66.             &bytes: SETA 4*&bytes
  67.         ELSEIF &size='W' THEN
  68.             &bytes: SETA 2*&bytes
  69.         ELSEIF &size='B' THEN
  70.         ELSE
  71.             AERROR &CONCAT('FREE: ',&size,' is a bad size.')
  72.         ENDIF
  73.         &bytes: SETA ((&bytes+1) AND (~1))
  74.         IF &bytes<32767 THEN
  75.             ADD.W #&bytes,SP
  76.         ELSE
  77.             ADD.L #&bytes,SP
  78.         ENDIF
  79.     ENDM
  80.  
  81. ;Move condition codes.
  82.     MACRO
  83.     MOVECCR    &destination
  84.         MOVE.W SR,&destination
  85.     ENDM
  86.  
  87. ;Save some registers on the stack, possibly changing the condition codes.
  88.     MACRO
  89.     Save ®isters,&preserve==0
  90.         GBLC &savedRegisters
  91.         GBLA &port
  92.         IF &savedRegisters<>'' THEN
  93.             AERROR 'Two Saves without an intervening Restore.'
  94.         ENDIF
  95.         &port: SETA 0
  96.         IF ®isters='' THEN
  97.             &savedRegisters: SETC 'None'
  98.         ELSEIF ®isters='thePort' THEN
  99.             &savedRegisters: SETC 'None'
  100.             &port: SETA 1
  101.         ELSE
  102.             IF &SubStr(®isters,&Len(®isters)-7,8)='/thePort' THEN
  103.                 &savedRegisters: SETC &SubStr(®isters,1,&Len(®isters)-8)
  104.                 &port: SETA 1
  105.             ELSE
  106.                 &savedRegisters: SETC ®isters
  107.             ENDIF
  108.             IF &SubStr(&Type(&savedRegisters),1,5)='REG A' THEN
  109.                 MOVE.L &savedRegisters,-(SP)
  110.             ELSEIF &SubStr(&Type(&savedRegisters),1,4)='REG ' THEN
  111.                 IF &preserve THEN
  112.                     MOVEM.L &savedRegisters,-(SP)
  113.                 ELSE
  114.                     MOVE.L &savedRegisters,-(SP)
  115.                 ENDIF
  116.             ELSE
  117.                 MOVEM.L &savedRegisters,-(SP)
  118.             ENDIF
  119.         ENDIF
  120.         IF &port THEN
  121.             RSRV.L
  122.             MOVEM.L D0-D2/A0-A1,-(SP)
  123.             IF &preserve THEN
  124.                 MOVECCR -(SP)
  125.                 PEA 2+5*4(SP)
  126.             ELSE
  127.                 PEA 5*4(SP)
  128.             ENDIF
  129.             _GetPort
  130.             IF &preserve THEN
  131.                 MOVE.W (SP)+,CCR
  132.             ENDIF
  133.             MOVEM.L (SP)+,D0-D2/A0-A1
  134.         ENDIF
  135.         IF debug THEN
  136.             PEA ('Save')
  137.         ENDIF
  138.     ENDM
  139.  
  140. ;Restore some registers saved by a Save macro.
  141.     MACRO
  142.     Restore &preserve==0
  143.         GBLC &savedRegisters
  144.         GBLA &port
  145.         IF &savedRegisters='' THEN
  146.             AERROR 'Restore without Save.'
  147.         ELSE
  148.             IF debug THEN
  149.                 IF &preserve THEN
  150.                     MOVECCR -(SP)
  151.                     CMP.L #'Save',2(SP)
  152.                 ELSE
  153.                     CMP.L #'Save',(SP)+
  154.                 ENDIF
  155.                 BEQ.S @goodSave
  156.                 _Debugger
  157.                 @goodSave:
  158.                 IF &preserve THEN
  159.                     MOVE.W (SP)+,CCR
  160.                     ADDQ.W #4,SP
  161.                 ENDIF
  162.             ENDIF
  163.             IF &port THEN
  164.                 IF &preserve THEN
  165.                     MOVECCR -(SP)
  166.                     MOVE.L 2(SP),-(SP)
  167.                     _SetPort
  168.                     MOVE.W (SP)+,CCR
  169.                     FREE.L
  170.                 ELSE
  171.                     MOVEM.L D0-D2/A0-A1,-(SP)
  172.                     IF &preserve THEN
  173.                         MOVECCR -(SP)
  174.                         MOVE.L 2+5*4(SP),-(SP)
  175.                     ELSE
  176.                         MOVE.L 5*4(SP),-(SP)
  177.                     ENDIF
  178.                     _SetPort
  179.                     IF &preserve THEN
  180.                         MOVE.W (SP)+,CCR
  181.                     ENDIF
  182.                     MOVEM.L (SP)+,D0-D2/A0-A1
  183.                     FREE.L
  184.                 ENDIF
  185.             ENDIF
  186.             IF &savedRegisters<>'None' THEN
  187.                 IF &SubStr(&Type(&savedRegisters),1,5)='REG A' THEN
  188.                     MOVE.L (SP)+,&savedRegisters
  189.                 ELSEIF &SubStr(&Type(&savedRegisters),1,4)='REG ' THEN
  190.                     IF &preserve THEN
  191.                         MOVEM.L (SP)+,&savedRegisters
  192.                     ELSE
  193.                         MOVE.L (SP)+,&savedRegisters
  194.                     ENDIF
  195.                 ELSE
  196.                     MOVEM.L (SP)+,&savedRegisters
  197.                 ENDIF
  198.             ENDIF
  199.             &savedRegisters: SETC ''
  200.         ENDIF
  201.     ENDM
  202.  
  203. ;Pad a piece of memory to BlockSize items (item is either bytes, words, or longs).
  204.     MACRO
  205.     Pad.&size &blockSize,&startLabel,&itemValue=0
  206.         LCLC &itemType
  207.         LCLA &padItems
  208.         &PadItems: SETA &Eval(&BlockSize)-(*-&Eval(&StartLabel))
  209.         IF &size='' THEN
  210.             &itemType: SETC 'B'
  211.         ELSEIF &size='B' THEN
  212.             &itemType: SETC 'B'
  213.         ELSEIF &size='W' THEN
  214.             &ItemType: SETC 'W'
  215.             &padItems: SETA &padItems DIV 2
  216.         ELSEIF &size='L' THEN
  217.             &itemType: SETC 'L'
  218.             &padItems: SETA &padItems DIV 4
  219.         ELSE
  220.             AERROR &Concat('Pad cannot handle unknown item length: ',&size)
  221.         ENDIF
  222.         IF &padItems<0 THEN
  223.             AERROR 'Pad cannot pad a block bigger than the block size.'
  224.         ELSEIF &padItems>0 THEN
  225.             DCB.&itemType &padItems,&itemValue
  226.         ENDIF
  227.     ENDM
  228.  
  229. ;Create a jump table starting with the label and having a given prefix.
  230.     MACRO
  231. &name    Table &prefix,&base
  232.         LCLC &tableName
  233.         GBLC &tablePrefix,&tableBase
  234.         IF &name = '' THEN
  235.             &tableName: SETC 'Table'
  236.         ELSE
  237.             &tableName: SETC &name
  238.         ENDIF
  239.         &tablePrefix: SETC &prefix
  240.         IF &base = '' THEN
  241.             &tableBase: SETC &tableName
  242.         ELSEIF &UpCase(&base) = 'ABSOLUTE' THEN
  243.             &tableBase: SETC ''
  244.         ELSE
  245.             &tableBase: SETC &base
  246.         ENDIF
  247.         &tableName:
  248.     ENDM
  249.  
  250. ;Create a jump table entry.
  251.     MACRO
  252.     DT.&size &entry
  253.         GBLC &tablePrefix,&tableBase
  254.         IF &tableBase = '' THEN
  255.             DC.&size &Concat(&tablePrefix,&entry)
  256.         ELSE
  257.             DC.&size &Concat(&tablePrefix,&entry,'-',&tableBase)
  258.         ENDIF
  259.     ENDM
  260.  
  261. ;Create a stack frame.
  262.     MACRO
  263. &frame    Frame ¶meters=0
  264.         GBLC &frameName,&frameState,&WITHStatus,&ENDWITHMod
  265.         IF &WITHStatus = 'NeedENDWITH' THEN
  266.             IF &SysMod = &ENDWITHMod THEN
  267.                 ENDWITH
  268.             ENDIF
  269.         ENDIF
  270.         &WITHStatus: SETC ''
  271.         IF &frameState = '' THEN
  272.             IF &frame = '' THEN
  273.                 &frameName: SETC 'Frame'
  274.             ELSE
  275.                 &frameName: SETC &frame
  276.             ENDIF
  277.             &frameName: RECORD {Link},DECR
  278.             FrameStart: EQU *
  279.             &frameState: SETC 'Frame'
  280.         ENDIF
  281.         IF &frameState = 'Frame' THEN
  282.             IF ¶meters = 0 THEN
  283.                 ORG
  284.                 ParameterSize: EQU FrameStart-*
  285.                 Return: DS.L 1
  286.                 Link: DS.L 1
  287.                 &frameState: SETC 'Link'
  288.             ENDIF
  289.         ELSE
  290.             AERROR 'Two Frames without intervening EndFrame.'
  291.         ENDIF
  292.     ENDM
  293.  
  294. ;Declare some parameters.
  295.     MACRO
  296. &Frme    ParameterFrame
  297. &Frme    Frame parameters=1
  298.     ENDM
  299.  
  300. ;Declare some locals.
  301.     MACRO
  302.     LocalFrame
  303.         Frame parameters=0
  304.     ENDM
  305.  
  306. ;End a stack frame.
  307.     MACRO
  308.     EndFrame
  309.         GBLC &frameName,&frameState,&WITHStatus
  310.         IF &frameState = 'Frame' THEN
  311.             Frame
  312.         ENDIF
  313.         IF &frameState = 'Link' THEN
  314.             ORG
  315.             LocalSize: EQU *
  316.             ENDR
  317.             &frameState: SETC ''
  318.             &WITHStatus: SETC 'NeedWITH'
  319.         ELSE
  320.             AERROR 'EndFrame without proper balancing Frame.'
  321.         ENDIF
  322.     ENDM
  323.  
  324. ;Hide the cursor.
  325.     MACRO
  326.     HideCursor
  327.         _HideCursor
  328.     ENDM
  329.  
  330. ;Show the cursor.
  331.     MACRO
  332.     ShowCursor
  333.         MOVE.B #1,CrsrBusy            ;lock out the cursor routines
  334.         CMP.W #-1,CrsrState            ;will the cursor be made visible?
  335.         BLT.S @doShow                ;no, don't unobscure
  336.         CLR.B CrsrObscure            ;turn off the obscure flag
  337.         @doShow:
  338.         _ShowCursor                ;start the cursor back up
  339.     ENDM
  340.  
  341. ;LINK.
  342.     MACRO
  343.     doLINK    &size
  344.         GBLC &LINKstate,&frameName,&WITHStatus,&ENDWITHMod
  345.         IF &LINKstate <> '' THEN
  346.             AERROR 'missing UNLK'
  347.         ENDIF
  348.         IF &WITHStatus = 'NeedWITH' THEN
  349.             WITH &frameName
  350.             &WITHStatus: SETC 'NeedENDWITH'
  351.             &ENDWITHMod: SETC &SysMod
  352.         ENDIF
  353.         IF &size='' THEN
  354.             LINK A6,#LocalSize
  355.         ELSE
  356.             LINK A6,#&size
  357.         ENDIF
  358.         IF debug THEN
  359.             PEA ('LINK')
  360.         ENDIF
  361.         &LINKState: SETC 'doLINK'
  362.     ENDM
  363.  
  364. ;Fake LINK.
  365.     MACRO
  366.     noLINK
  367.         GBLC &LINKstate
  368.         IF &LINKstate <> '' THEN
  369.             AERROR 'missing UNLK'
  370.         ENDIF
  371.         IF debug THEN
  372.             LINK A6,#0
  373.             UNLK A6
  374.         ENDIF
  375.         &LINKState: SETC 'noLINK'
  376.     ENDM
  377.  
  378. ;UNLK.
  379.     MACRO
  380.     doUNLK    &preserve==0
  381.         GBLC &LINKstate
  382.         IF &LINKstate = '' THEN
  383.             AERROR 'missing LINK'
  384.         ENDIF
  385.         IF &LINKstate = 'doLINK' THEN
  386.             IF debug THEN
  387.                 IF &preserve THEN
  388.                     MOVECCR -(SP)
  389.                     CMP.L #'LINK',2(SP)
  390.                 ELSE
  391.                     CMP.L #'LINK',(SP)+
  392.                 ENDIF
  393.                 BEQ.S @goodUNLK
  394.                 _Debugger
  395.                 @goodUNLK:
  396.                 IF &preserve THEN
  397.                     MOVE.W (SP)+,CCR
  398.                     ADDQ.W #4,SP
  399.                 ENDIF
  400.             ENDIF
  401.             UNLK A6
  402.         ELSE
  403.             IF debug THEN
  404.                 BRA.S @skipUNLK
  405.                 UNLK A6
  406.                 @skipUNLK:
  407.             ENDIF
  408.         ENDIF
  409.         &LINKState: SETC ''
  410.     ENDM
  411.  
  412. ;Fake RTS.
  413.     MACRO
  414.     noRTS
  415.         IF debug THEN
  416.             BRA.S @skipRTS
  417.             RTS
  418.             @skipRTS:
  419.         ENDIF
  420.     ENDM
  421.  
  422. ;RTS.
  423.     MACRO
  424.     doRTS
  425.         RTS
  426.     ENDM
  427.  
  428. ;RTD (uses A0).
  429.     MACRO
  430.     doRTD    &size
  431.         LCLA &bytes
  432.         IF &size = '' THEN
  433.             &bytes: SETA ParameterSize
  434.         ELSEIF &SubStr(&size, 1, 1) = '#' THEN
  435.             &bytes: SETA &StrToInt(&SubStr(&size, 2, &Length(&size)-1))
  436.         ELSE
  437.             AERROR 'doRTD: bad size'
  438.         ENDIF
  439.         IF &bytes = 0 THEN
  440.             RTS
  441.         ELSEIF &bytes = 4 THEN
  442.             MOVE.L (SP)+,(SP)
  443.             RTS
  444.         ELSEIF &bytes <= 8 THEN
  445.             MOVE.L (SP)+,A0
  446.             ADDQ.W #&bytes,SP
  447.             JMP (A0)
  448.         ELSE
  449.             MOVE.L (SP)+,A0
  450.             LEA &bytes(SP),SP
  451.             JMP (A0)
  452.         ENDIF
  453.     ENDM
  454.  
  455. ;Symbol.
  456.     MACRO
  457.     Symbol &routineName
  458.         LCLC &name
  459.         IF debug THEN
  460.             IF &routineName='' THEN
  461.                 &name: SETC &SysMod
  462.             ELSEIF &routineName[1]='''' THEN
  463.                 &name: SETC &SubStr(&routineName,2,&Len(&routineName)-2)
  464.             ELSE
  465.                 &name: SETC &routineName
  466.             ENDIF
  467.             &name: SETC &SubStr(&Concat(&name, '        '),1,8)
  468.             DC.B &Ord(&name[1])+$80,&Ord(&name[2]),&Ord(&name[3]),&Ord(&name[4])
  469.             DC.B &Ord(&name[5]),&Ord(&name[6]),&Ord(&name[7]),&Ord(&name[8])
  470.         ENDIF
  471.     ENDM
  472.  
  473. ;Define constant storage.
  474.     MACRO
  475.     DCS &recordName
  476.         DCB.B &recordName..size,0
  477.     ENDM
  478.  
  479. ;Set up a patch table.
  480.     MACRO
  481.     PatchTable &thePatchStart
  482.         GBLC &patchStart
  483.         &patchStart: SETC &thePatchStart
  484.     ENDM
  485.  
  486. ;Set up a patch table entry.
  487.     MACRO
  488.     DP    &key,&patch,&old
  489.         GBLC &patchStart
  490.         IF &key='' THEN
  491.             DC.W 0
  492.         ELSE
  493.             DC.W &key
  494.             IF &patch='' THEN
  495.                 DC.W 0
  496.             ELSE
  497.                 DC.W Patch&patch-&patchStart
  498.             ENDIF
  499.             IF &old='' THEN
  500.                 DC.W 0
  501.             ELSE
  502.                 DC.W Old&old-&patchStart
  503.             ENDIF
  504.         ENDIF
  505.     ENDM
  506.  
  507. ;Set up a JMP to be patched.
  508.     MACRO
  509.     PJMP &label
  510.         DC.W $4EF9
  511.         Old&label: DC.L 0
  512.     ENDM
  513.  
  514. ;Set up a JSR to be patched.
  515.     MACRO
  516.     PJSR &label
  517.         DC.W $4EB9
  518.         Old&label: DC.L 0
  519.     ENDM
  520.  
  521.